#pragma once
#include <string>
#include <vector>
#include <sstream>
#include <iomanip>
#include "String.h"
#include "Object.h"

namespace yzrilyzr_lang{
	EBCLASS(ObjectUtil){
	public:
	static String formatDouble(double value, const String & formatSpec){
			// 解析格式说明符，如 %.2f
		u_index precision=6; // 默认精度
		bool hasPrecision=false;
		u_index dotPos=formatSpec.indexOf('.');

		if(dotPos >= 0){
			try{
				precision=std::stoul(formatSpec.substring(dotPos + 1).tostring());
				hasPrecision=true;
			} catch(...){
				// 保持默认精度
			}
		}

		std::ostringstream oss;
		oss << std::fixed;
		if(hasPrecision){
			oss << std::setprecision(precision);
		}
		oss << value;

		std::string result=oss.str();

		// 移除不必要的尾随零和小数点
		if(hasPrecision){
			u_index dotPos=result.find('.');
			if(dotPos != std::string::npos){
				// 移除尾随的零
				result.erase(result.find_last_not_of('0') + 1);
				// 如果只剩下小数点，也移除
				if(result.back() == '.'){
					result.pop_back();
				}
			}
		}

		return result;
	}
	template<typename T>
	static String toString(const T &value){
		if constexpr(std::is_same_v<T, bool>){
			return value?"true":"false";
		} else if constexpr(std::is_integral_v<T>){
			return std::to_string(value);
		} else if constexpr(std::is_floating_point_v<T>){
			return formatDouble(value, "");
		} else if constexpr(std::is_convertible_v<T, std::string>){
			return String(value);
		} else if constexpr(std::is_convertible_v<T, BaseObject>){
			return value.toString();
		} else if constexpr(std::is_convertible_v<T, BaseObject *>){
			if(value == nullptr)return U_NULL_STRING;
			return value->toString();
		} else if constexpr(std::is_convertible_v<T, std::shared_ptr<BaseObject>>){
			if(value == nullptr)return U_NULL_STRING;
			return value->toString();
		}
		return "Unsupported type for string formatting";
	}
	template<typename T>
	static int32_t hashCode(const T & value){
		if constexpr(std::is_same_v<T, bool>){
			return value?1:0;
		} else if constexpr(std::is_integral_v<T>){
			return value;
		} else if constexpr(std::is_floating_point_v<T>){
			return value;
		} else if constexpr(std::is_convertible_v<T, std::string>){
			return String(value).hashCode();
		} else if constexpr(std::is_convertible_v<T, BaseObject>){
			return value.hashCode();
		} else if constexpr(std::is_convertible_v<T, BaseObject *>){
			if(value == nullptr)return 0;
			return value->hashCode();
		} else if constexpr(std::is_convertible_v<T, std::shared_ptr<BaseObject>>){
			if(value == nullptr)return 0;
			return value->hashCode();
		}
		return -1;
	}
	};
}